package com.lyf.core.util;

import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.web.bind.annotation.RequestMapping;

import com.lyf.core.compant.Perm;
import com.lyf.core.pojo.Menu;

public class CommonUtils {

	 
	public final static String md5(String key , String value) {
		
		 
		return md5(key + "_" + value);
	}
	
	 public final static String md5(String s) {
	        char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};       
	        try {
	            byte[] btInput = s.getBytes();
	            // 获得MD5摘要算法的 MessageDigest 对象
	            MessageDigest mdInst = MessageDigest.getInstance("MD5");
	            // 使用指定的字节更新摘要
	            mdInst.update(btInput);
	            // 获得密文
	            byte[] md = mdInst.digest();
	            // 把密文转换成十六进制的字符串形式
	            int j = md.length;
	            char str[] = new char[j * 2];
	            int k = 0;
	            for (int i = 0; i < j; i++) {
	                byte byte0 = md[i];
	                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
	                str[k++] = hexDigits[byte0 & 0xf];
	            }
	            return new String(str);
	        } catch (Exception e) {
	            e.printStackTrace();
	            return null;
	        }
	    }

	public static int getcgi(int lac , int ci) {
		
		if(lac < 65535) {
			
			return lac << 16 | ci ;
			
		} else {
			return lac << 8 | ci ;
		}
		
	}
	
	
	public static Long sum(List<Integer> list) {
		
		long sum = 0 ;
		
		for(Integer i : list) {
			sum += i ;
		}
		return sum ;
	}
	  
	
	public static Integer avg(List<Integer> list ) {
		
		long sum = sum(list);
		
		return Math.round(sum / list.size()) ;
		
	}
	
	
 
	
	/**
	 * 获取上个月的月份ID
	 * @param month_id
	 * @return
	 */
	public static int getPreMonth(int month_id) {
		
		Calendar calendar = Calendar.getInstance();
		calendar.set(month_id / 100,  month_id % 100 - 1, 1);
		
		
		//减去一月
		calendar.add(Calendar.MONTH, -1);
		
		
		int preMonthid = calendar.get(Calendar.YEAR) * 100 + (calendar.get(Calendar.MONTH) +1  );
		
		
		return preMonthid;
		
	}
	
	public static Date parseDate(String format , String value) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		
		try {
			return sdf.parse(value);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
	
	public static String formatDate(String format , Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		
		return sdf.format(date);
		
	}
	
	/**
	   *

	   *  去掉指定字符串的开头和结尾的指定字符
	   * 

	   *
	   * @param stream 要处理的字符串
	   * @param trimstr 要去掉的字符串
	   * @return 处理后的字符串
	   */
	  public static String sideTrim(String stream, String trimstr) {
	    // null或者空字符串的时候不处理
	    if (stream == null || stream.length() == 0 || trimstr == null || trimstr.length() == 0) {
	      return stream;
	    }
	 
	    // 结束位置
	    int epos = 0;
	 
	    // 正规表达式
	    String regpattern = "[" + trimstr + "]*+";
	    Pattern pattern = Pattern.compile(regpattern, Pattern.CASE_INSENSITIVE);
	 
	    // 去掉结尾的指定字符 
	    StringBuffer buffer = new StringBuffer(stream).reverse();
	    Matcher matcher = pattern.matcher(buffer);
	    if (matcher.lookingAt()) {
	      epos = matcher.end();
	      stream = new StringBuffer(buffer.substring(epos)).reverse().toString();
	    }
	 
	    // 去掉开头的指定字符 
	    matcher = pattern.matcher(stream);
	    if (matcher.lookingAt()) {
	      epos = matcher.end();
	      stream = stream.substring(epos);
	    }
	 
	    // 返回处理后的字符串
	    return stream;
	  }
	  
	  /**
	   * 返回 #{} 或者 ${} 中包含的值
	   * @param str
	   * @param type
	   * @return eg:#{name} ${ages} 
	   */
	  public static String[] getWildcard(String str ) {
		  
		 List<String> list = new ArrayList<String>();
		 
		 int start = 0;
		 while(start < str.length() && start >= 0) {
			 
			 start = str.indexOf("{", start);
			 
			 int end = str.indexOf("}", start);
			 if(start > 0) {
				 String wc = str.substring(start - 1 , end + 1);
				 
				 list.add(wc);
			 }
			
			 if(start < 0) break ;
			 
			 start = end + 1;
			 
		 }
		 
		 return list.toArray(new String[0]);
		  
	  }
	  
	 
	  
	  /**
	   * 判断是否为数字
	   * @param v
	   * @return
	   */
	  public static boolean isNumber(Object v) {
		  
		  if(v == null) return false; 
		  
		  if(v instanceof Number) {
			  return true ;
		  } else if(v.toString().matches("^\\d+$")) {
			  return true ;
		  } else if(v.toString().matches("^-?\\d+\\.?\\d+$")) {
			  return true ;
		  } else {
			  try{
				  Double.parseDouble(v.toString());
				  return true ;
			  }catch(Exception e) {
				  return false;
			  }
			 
			  
		  }
		  
	  }
	  
	  
	  
	  /**
	   * 判断是否有当前地市的权限
	   * @param mycitid 自己的所属地市
	   * @param citid 要判断是否有权限的地市
	   * @return 有权限返回true,反之返回false
	   */
	  public static boolean authority(int mycitid , int citid) {
		  return  sideTrim(String.valueOf(citid ), "0") .startsWith(sideTrim(String.valueOf(mycitid ), "0"));
	  }
	  
	  
	  public static Collection<Perm> getAllPerms() {
		   
		  Map<String, Perm> map = getAllUrlPerms();
		  
		  return map.values();
		  
	  }
	  
	 private static Map<String, Perm> perm_buffer = new ConcurrentHashMap<>();
	 
	 private static List<Menu> menus_all = new LinkedList<>();
	 
	 private static Map<String, Menu> id_menu_buffer = new ConcurrentHashMap<>();
	 
	 public static Map<String, Menu> getMenuMap() {
		 if(id_menu_buffer != null && !id_menu_buffer.isEmpty()){
			 return id_menu_buffer ;
		 }
		 
		 List<Menu> menus = getMenus(false, false, null);
		 for(Menu m : menus) {
			 id_menu_buffer.put(m.getMenu_id(), m);
		 }
		 
		return id_menu_buffer;
	 }
	 
	 /**
	  * 获取所有菜单信息
	  * @param isPage 是否页面
	  * @param orderChild 是否以子菜单形式进行组合
	  * @return
	  */
	 public static List<Menu> getMenus(boolean onlyPage , boolean orderChild , IFilter<Menu> filter){
		 
		 if(menus_all == null || menus_all.isEmpty()) {
			 Map<String, Perm> sp = CommonUtils.getAllUrlPerms();
			  
			 	//返回最上一级
			for(Entry<String, Perm> entry : sp.entrySet()) {
 
				
				Menu m = new Menu();
				m.setMenu_id(entry.getValue().id());
				m.setMenu_name(entry.getValue().name());
				m.setParent_id(entry.getValue().parentId());
				m.setIs_visible(true);
				m.setMenu_url(entry.getKey());
				m.setMenu_type(entry.getValue().isPage() ? 1 : 2);
				 
				if(m.getMenu_url() != null && m.getMenu_url().startsWith("/")){
					m.setMenu_url("." + m.getMenu_url());
				}
				
				menus_all.add(m);
	  
			}
			 
			 
		 }
		 
		 if(!onlyPage && !orderChild && filter == null) return menus_all ;
		 

		 List<Menu> ms = new LinkedList<>();
		
		 
		 if(onlyPage) {
			 for(Menu m : menus_all)  { 
				 if(m.getMenu_type() == 1){
					 ms.add(m);
				 } 
			 }
			  
		 } else {
			 ms.addAll(menus_all);
		 }
		 
		 
		 if(filter != null) {
			 
			 Iterator<Menu> iters = ms.iterator();
			 while(iters.hasNext()) {
				 Menu m = iters.next();
				 if(!filter.filter(m)){
					 iters.remove();
				 }
			 }
			 
			 
		 } 
		 
		 if(orderChild) {
			  
			 return childsMenu(ms) ;
		 } else {
			 return ms ;
		 }
		 
		  
	 }
	 
	 /**
	  * 按照一级级的顺序排列菜单
	  * @param sources
	  * @return
	  */
	 public static List<Menu> childsMenu(List<Menu> sources){
		 List<Menu> orderMenus = new LinkedList<>();
		 
		 for(Menu m : sources)  { 
			 String p_id = m.getParent_id();
			 
			 if(p_id == null || p_id.equals("")){
				 orderMenus.add(m);
			 } 
		 }
		 
		 //子菜单组合
		//顶层钻取
		 for(Menu m : orderMenus) {
			 
			 itersMenus(sources, m);
		 }
		 
		 return orderMenus ;
	 }
	 
	 private static void itersMenus(List<Menu> sources , Menu m) {
		 
		 if(m.getChildren() != null){
			 m.getChildren().clear();
		 }
		 
		 for(Menu _m : sources) {
			 String p_id = _m.getParent_id();
			 if(m.getMenu_id().equals(p_id)) {
				 m.addChild(_m);
				 //下钻
			 }
		 }
		 
		 if(m.getChildren() != null && !m.getChildren().isEmpty()) {
			 //m.setState(  "closed");
			 for(Menu _m : m.getChildren()) {
				 itersMenus(sources, _m);
			 }
		 } else {
			// m.setState("open");
		 }
		 
	 }
	  
	 public static  Map<String, Perm>  getAllUrlPerms() {
		  
		 if(perm_buffer != null && !perm_buffer.isEmpty()) {
			 return perm_buffer ;
		 }
		  
		 Set<Class<?>> cs =	ClassService.getClasses("com.lyf");

		 if(cs == null || cs.isEmpty()) return perm_buffer;
		 
		 for(Class<?> c : cs) {
			 if(!c.isAnnotationPresent(Perm.class) || !c.isAnnotationPresent(RequestMapping.class)) continue ;
 
			 Method[] ms = c.getMethods();

			 String[] cUrl = c.getAnnotation(RequestMapping.class).value();
			 
			 for(Method m : ms) {
				 if(!m.isAnnotationPresent(Perm.class) || !c.isAnnotationPresent(RequestMapping.class)) continue ; 
				 Perm p_method = m.getAnnotation(Perm.class);
				  
				

				 String[] mUrl = m.getAnnotation(RequestMapping.class).value();
				 
				 perm_buffer.put(cUrl[0] + mUrl[0], p_method);
				 
				//  System.out.println(cUrl[0] + mUrl[0] + " , " + p_method.name());
			 }
 
			 perm_buffer.put(cUrl[0]  , c.getAnnotation(Perm.class));
		 }
			 
		 return perm_buffer;
	 }
	 
	 public static void main(String[] args) {
		
		 Collection<Perm> list = getAllPerms();
		 
		 for(Perm p : list) {
			 System.out.println(p.id() + "," + p.model() + "," + p.name() + "," + p.parentId());
		 }
		
		 
		 
		
		
	}
	 
	 
	 
}
